package io.renren.common.utils;

import io.renren.common.annotation.OpenApi;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
import org.springframework.core.type.filter.AnnotationTypeFilter;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * @auther xiegaolong
 * @description
 * @date 2024/12/2
 */
public class OpenApiFactory {

    private static List<String> openApiList = new ArrayList<>();

    static {
        init();
    }

    private static void init(){
        List<String>  list = new ArrayList<>();

        ClassPathScanningCandidateComponentProvider scanner =
                new ClassPathScanningCandidateComponentProvider(false);
        scanner.addIncludeFilter(new AnnotationTypeFilter(RequestMapping.class));
        Set<BeanDefinition> components = scanner.findCandidateComponents("io.renren.modules.api");

        for (BeanDefinition component : components) {
            String clsOpenURL = "";
            String methodURL = getMethodURL(component);
            if (StringUtils.isNotEmpty(methodURL)){
                clsOpenURL = getClsOpenURL(component);
                list.add(clsOpenURL+methodURL);
            }
        }
        openApiList = list;
    }

    private static final String getClsOpenURL(BeanDefinition component){
        try {
            Class<?> aClass = Class.forName(component.getBeanClassName());
            RequestMapping requestMapping = aClass.getAnnotation(RequestMapping.class);
            if (requestMapping != null){
                String[] value = requestMapping.value();
                if (value != null && value.length > 0){
                    if (!value[0].startsWith("/")){
                        return "/"+value[0];
                    }
                }
                return value[0];
            }
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        }
        return "";
    }

    private static final String getMethodURL(BeanDefinition component){
        try {
            Class<?> aClass = Class.forName(component.getBeanClassName());
            Method[] methods = aClass.getMethods();
            for(Method tmpMethod: methods){
                OpenApi annotation = tmpMethod.getAnnotation(OpenApi.class);
                if (annotation != null){
                    PostMapping postAnno = tmpMethod.getAnnotation(PostMapping.class);
                    if (postAnno != null){
                        String[] value = postAnno.value();
                        if (value != null && value.length > 0){
                            if (!value[0].startsWith("/")){
                                return "/"+value[0];
                            }
                        }
                        return value[0];
                    }
                }
            }
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        }
        return "";
    }


    public static List<String> getOpenApiList(){
        return openApiList;
    }
}
